import React, { useMemo } from 'react';
import { useEditorStore } from '../store/useEditorStore';
import { parseYAML } from '../utils/yaml';
import { PreviewMode } from '../types';
import { ChevronDown, ChevronRight, FileText, Hash, Type, ToggleLeft, ToggleRight, List, Braces } from 'lucide-react';

interface YamlPreviewProps {
  className?: string;
}

interface TreeNodeProps {
  data: any;
  path: string;
  level: number;
  expanded: boolean;
  onToggle: (path: string) => void;
}

const TreeNode: React.FC<TreeNodeProps> = ({ data, path, level, expanded, onToggle }) => {
  const isObject = data !== null && typeof data === 'object' && !Array.isArray(data);
  const isArray = Array.isArray(data);
  const isExpandable = isObject || isArray;
  const hasChildren = isExpandable && (isObject ? Object.keys(data).length > 0 : data.length > 0);

  const getValueIcon = (value: any) => {
    if (value === null || value === undefined) return <Hash className="w-4 h-4 text-gray-400" />;
    if (typeof value === 'string') return <Type className="w-4 h-4 text-green-600" />;
    if (typeof value === 'number') return <Hash className="w-4 h-4 text-blue-600" />;
    if (typeof value === 'boolean') return value ? <ToggleRight className="w-4 h-4 text-purple-600" /> : <ToggleLeft className="w-4 h-4 text-purple-600" />;
    if (Array.isArray(value)) return <List className="w-4 h-4 text-orange-600" />;
    if (typeof value === 'object') return <Braces className="w-4 h-4 text-indigo-600" />;
    return <FileText className="w-4 h-4 text-gray-600" />;
  };

  const getValuePreview = (value: any): string => {
    if (value === null || value === undefined) return 'null';
    if (typeof value === 'string') return `"${value.length > 50 ? value.substring(0, 50) + '...' : value}"`;
    if (typeof value === 'number' || typeof value === 'boolean') return String(value);
    if (Array.isArray(value)) return `Array(${value.length})`;
    if (typeof value === 'object') return `Object(${Object.keys(value).length})`;
    return String(value);
  };

  const renderValue = (value: any, key?: string) => {
    const indent = level * 20;
    
    if (!isExpandable) {
      return (
        <div 
          className="flex items-center py-1 hover:bg-gray-50 dark:hover:bg-gray-800 rounded px-2"
          style={{ paddingLeft: `${indent + 8}px` }}
        >
          {getValueIcon(value)}
          {key && (
            <span className="font-medium text-gray-700 dark:text-gray-300 mr-2">
              {key}:
            </span>
          )}
          <span className="text-gray-600 dark:text-gray-400 font-mono text-sm">
            {getValuePreview(value)}
          </span>
        </div>
      );
    }

    return (
      <div>
        <div 
          className="flex items-center py-1 hover:bg-gray-50 dark:hover:bg-gray-800 rounded px-2 cursor-pointer"
          style={{ paddingLeft: `${indent}px` }}
          onClick={() => hasChildren && onToggle(path)}
        >
          {hasChildren ? (
            expanded ? (
              <ChevronDown className="w-4 h-4 text-gray-500 mr-1" />
            ) : (
              <ChevronRight className="w-4 h-4 text-gray-500 mr-1" />
            )
          ) : (
            <div className="w-5 mr-1" />
          )}
          {getValueIcon(value)}
          {key && (
            <span className="font-medium text-gray-700 dark:text-gray-300 mr-2">
              {key}:
            </span>
          )}
          <span className="text-gray-600 dark:text-gray-400 font-mono text-sm">
            {getValuePreview(value)}
          </span>
        </div>
        
        {expanded && hasChildren && (
          <div>
            {isArray ? (
              data.map((item: any, index: number) => (
                <TreeNode
                  key={`${path}[${index}]`}
                  data={item}
                  path={`${path}[${index}]`}
                  level={level + 1}
                  expanded={true}
                  onToggle={onToggle}
                />
              ))
            ) : (
              Object.entries(data).map(([childKey, childValue]) => (
                <TreeNode
                  key={`${path}.${childKey}`}
                  data={childValue}
                  path={`${path}.${childKey}`}
                  level={level + 1}
                  expanded={true}
                  onToggle={onToggle}
                />
              ))
            )}
          </div>
        )}
      </div>
    );
  };

  return renderValue(data, path.split('.').pop()?.replace(/\[\d+\]$/, ''));
};

const YamlPreview: React.FC<YamlPreviewProps> = ({ className = '' }) => {
  const { content, previewMode } = useEditorStore();
  const [expandedNodes, setExpandedNodes] = React.useState<Set<string>>(new Set(['root']));

  // 解析YAML内容
  const parsedData = useMemo(() => {
    if (!content.trim()) return null;
    
    try {
      return parseYAML(content);
    } catch (error) {
      return { error: error instanceof Error ? error.message : 'Unknown error' };
    }
  }, [content]);

  // 切换节点展开状态
  const toggleNode = (path: string) => {
    const newExpanded = new Set(expandedNodes);
    if (newExpanded.has(path)) {
      newExpanded.delete(path);
    } else {
      newExpanded.add(path);
    }
    setExpandedNodes(newExpanded);
  };

  // 渲染JSON格式
  const renderJsonView = () => {
    if (!parsedData) {
      return (
        <div className="text-gray-500 text-center py-8">
          <FileText className="w-12 h-12 mx-auto mb-2 opacity-50" />
          <p>暂无内容</p>
        </div>
      );
    }

    if (parsedData && typeof parsedData === 'object' && 'error' in parsedData) {
      return (
        <div className="text-red-500 p-4 bg-red-50 dark:bg-red-900/20 rounded border border-red-200 dark:border-red-800">
          <h3 className="font-semibold mb-2">解析错误</h3>
          <pre className="text-sm whitespace-pre-wrap font-mono">{parsedData.error}</pre>
        </div>
      );
    }

    return (
      <pre className="text-sm font-mono whitespace-pre-wrap p-4 bg-gray-50 dark:bg-gray-900 rounded border overflow-auto">
        {JSON.stringify(parsedData, null, 2)}
      </pre>
    );
  };

  // 渲染树形视图
  const renderTreeView = () => {
    if (!parsedData) {
      return (
        <div className="text-gray-500 text-center py-8">
          <FileText className="w-12 h-12 mx-auto mb-2 opacity-50" />
          <p>暂无内容</p>
        </div>
      );
    }

    if (parsedData && typeof parsedData === 'object' && 'error' in parsedData) {
      return (
        <div className="text-red-500 p-4 bg-red-50 dark:bg-red-900/20 rounded border border-red-200 dark:border-red-800">
          <h3 className="font-semibold mb-2">解析错误</h3>
          <pre className="text-sm whitespace-pre-wrap font-mono">{parsedData.error}</pre>
        </div>
      );
    }

    return (
      <div className="p-2">
        <TreeNode
          data={parsedData}
          path="root"
          level={0}
          expanded={expandedNodes.has('root')}
          onToggle={toggleNode}
        />
      </div>
    );
  };

  return (
    <div className={`h-full flex flex-col ${className}`}>
      {/* 预览模式切换 */}
      <div className="flex-shrink-0 border-b border-gray-200 dark:border-gray-700 p-2">
        <div className="flex space-x-1">
          <button
            onClick={() => useEditorStore.getState().setPreviewMode('tree')}
            className={`px-3 py-1 text-sm rounded transition-colors ${
              previewMode === 'tree'
                ? 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300'
                : 'text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800'
            }`}
          >
            <List className="w-4 h-4 inline mr-1" />
            树形视图
          </button>
          <button
            onClick={() => useEditorStore.getState().setPreviewMode('json')}
            className={`px-3 py-1 text-sm rounded transition-colors ${
              previewMode === 'json'
                ? 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300'
                : 'text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-800'
            }`}
          >
            <Braces className="w-4 h-4 inline mr-1" />
            JSON格式
          </button>
        </div>
      </div>

      {/* 预览内容 */}
      <div className="flex-1 overflow-auto">
        {previewMode === 'tree' ? renderTreeView() : renderJsonView()}
      </div>
    </div>
  );
};

export default YamlPreview;